package cn.codingjc.framework.common.util.download.core;

import cn.codingjc.framework.common.util.download.util.FileUtils;
import cn.codingjc.framework.common.util.download.util.HttpUtils;
import cn.hutool.Hutool;
import cn.hutool.core.util.StrUtil;
import cn.hutool.log.Log;
import com.google.errorprone.annotations.Var;
import lombok.extern.slf4j.Slf4j;

import java.io.BufferedInputStream;
import java.io.FileNotFoundException;
import java.io.InputStream;
import java.io.RandomAccessFile;
import java.net.HttpURLConnection;
import java.util.concurrent.Callable;

/**
 * @ClassName DownloadThread
 * @Description 下载文件线程
 * @Author jccoding
 * @Date 2024/3/10 22:13
 * @Version 1.0
 **/

@Slf4j
public class DownloadThread implements Callable<Boolean> {

    /**
     * 每次读取的数据块大小
     */
    private static int BYTE_SIZE = 1024 * 100;

    private static final String FILE_TEMP_SUFFIX = ".temp";

    /**
     * 下载链接
     */
    private String url;

    /**
     * 下载开始位置
     */
    private long startPos;

    /**
     * 要下载的文件区块大小
     */
    private Long endPos;

    /**
     * 标识多线程下载切分的第几部分
     */
    private Integer part;

    /**
     * 文件总大小
     */
    private Long contentLenth;

    public DownloadThread(String url, long startPos, Long endPos, Integer part, Long contentLenth) {
        this.url = url;
        this.startPos = startPos;
        this.endPos = endPos;
        this.part = part;
        this.contentLenth = contentLenth;
    }

    @Override
    public Boolean call() throws Exception {
        if (StrUtil.isEmpty(url)) {
            throw new RuntimeException("url is empty!");
        }
        // 文件名
        String httpFileName = HttpUtils.getHttpFileName(url);
        if (part != null) {
            httpFileName = httpFileName + FILE_TEMP_SUFFIX + part;
        }
        long fileContentLength = FileUtils.getFileContentLength(httpFileName);
        if (fileContentLength >= endPos - startPos) {
            log.info("文件已下载完成！");
            return true;
        }
        if (endPos.equals(contentLenth)) {
            endPos = null;
        }

        HttpURLConnection httpUrlConnection = HttpUtils.getHttpFileContentLength(url, startPos, endPos);
        try (InputStream is = httpUrlConnection.getInputStream();
             BufferedInputStream bis = new BufferedInputStream(is);
             RandomAccessFile randomAccessFile = new RandomAccessFile(httpFileName, "rw")) {
            randomAccessFile.seek(fileContentLength);
            byte[] buffer = new byte[BYTE_SIZE];
            int len = -1;
            // 读到文件末尾则返回-1
            while ((len = bis.read(buffer)) != -1) {
                randomAccessFile.write(buffer, 0, len);
//                LogThread.DOWNLOAD_SIZE.addAndGet(len);
            }
        } catch (FileNotFoundException e) {
            log.error("ERROR! 要下载的文件路径不存在 {} ", url);
            return false;
        } catch (Exception e) {
            log.error("下载出现异常");
            e.printStackTrace();
            return false;
        } finally {
            httpUrlConnection.disconnect();
//            LogThread.DOWNLOAD_FINISH_THREAD.addAndGet(1);
        }
        return true;
    }
}
